package com.github.wxiaoqi.security.crm.core.biz;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.wxiaoqi.security.auth.common.util.SnowFlake;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.crm.core.entity.CustomerBase;
import com.github.wxiaoqi.security.crm.core.entity.CustomerBaseAuths;
import com.github.wxiaoqi.security.crm.core.entity.PersonalBase;
import com.github.wxiaoqi.security.crm.core.entity.PersonalDistributionRelation;
import com.github.wxiaoqi.security.crm.core.mapper.CustomerBaseAuthsMapper;
import com.github.wxiaoqi.security.crm.core.mapper.CustomerBaseMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalBaseMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalDistributionRelationMapper;

import net.sf.json.JSONObject;

/**
 * 客户授权信息
 *
 * @author centerroot
 * @email ${email}
 * @date 2018-07-16 10:15:49
 */
@Service
public class CustomerBaseAuthsBiz extends BaseBiz<CustomerBaseAuthsMapper,CustomerBaseAuths> {

	private static final Logger logger = (Logger) LoggerFactory.getLogger(CustomerBaseAuthsBiz.class);

	@Autowired
	private CustomerBaseAuthsMapper customerBaseAuthsMapper;
	@Autowired
	private PersonalBaseMapper personalBaseMapper;
	@Autowired
	private CustomerBaseMapper customerBaseMapper;
	@Autowired
	private PersonalDistributionRelationMapper relationMapper;


	/**
	 * 微信小程序授权
	 * @param request
	 * @return
	 */
	public Map<String, Object> wechatMiniProgramAuth(Map<String, Object> request){
		logger.info("微信授权请求。。。。。。{}", request);
		Map<String, Object> response = new HashMap<String, Object>();
		String platformId = (String) request.get("platformId");
		String merchantId = (String) request.get("merchantId");
		String code = (String) request.get("code");
		String isScanQr = (String) request.get("isScanQr");
		String inviteId = (String) request.get("inviteId");
		Map<String, Object> inviteMap = new HashMap<>();
		StringBuilder url = new StringBuilder();
		url.append("https://api.weixin.qq.com/sns/jscode2session?");
		url.append("appid=wx6225d2d623ff1b40");
		url.append("&secret=548bc84204dba0e8abd6402dbb04f2a2");
		url.append("&js_code=").append(code);
		url.append("&grant_type=authorization_code");
		String data = null;
		try {
			logger.info("小程序获取openId第三方请求参数------{}", url.toString());
			data = wxSmallGetOpenId(url.toString());
		} catch (Exception e) {
			e.printStackTrace();
			response.put("code", "400101");
			response.put("msg", "小程序授权失败");
			logger.info("微信授权响应。。。。。。{}", response);
			return response;
		}
		logger.info("小程序获取openId第三方返回参数------{}", JSONObject.fromObject(data));
		JSONObject json = JSONObject.fromObject(data);
		String openId = String.valueOf(json.get("openid"));

		String customerId = String.valueOf(SnowFlake.getId());
		String personalId = String.valueOf(SnowFlake.getId());

		CustomerBaseAuths customerBaseAuths = new CustomerBaseAuths();
		customerBaseAuths.setPlatformId(platformId);
		customerBaseAuths.setCustomerType("CUST02");//用户
		customerBaseAuths.setAuthType("00");//登录授权
		customerBaseAuths.setAuthMethod("weixin");//微信
		customerBaseAuths.setIsthird("01");//第三方
		customerBaseAuths.setCredential(openId);
		CustomerBaseAuths selectAuthsInfo = customerBaseAuthsMapper.selectOne(customerBaseAuths);

		if(null == selectAuthsInfo){
			//为空则进行授权 
			customerBaseAuths.setCustomerId(customerId);
			customerBaseAuthsMapper.insert(customerBaseAuths);
			customerId = customerBaseAuths.getCustomerId();
			if ("01".equals(isScanQr)) {
				//执行邀请关系
				//相等说明自己邀请自己
				if(inviteId.equals(customerId)){
					inviteMap.put("code", "01");
					inviteMap.put("msg", "不能邀请自己");
				}else {
					inviteMap = saveInvieteRelation(platformId, customerId, inviteId);
				}
			}
		}else{
			//已经是会员或者已经被邀请过
			inviteMap.put("code", "01");
			inviteMap.put("msg", "用户已经是会员不能被重复邀请");
			customerId = selectAuthsInfo.getCustomerId();
		}

		//判断用户基础信息表是否存在该用户
		CustomerBase customerBase = new CustomerBase();
		customerBase.setPlatformId(platformId);
		customerBase.setCustomerId(customerId);
		customerBase.setMerchantId(merchantId);
		CustomerBase selectCustomerBase = customerBaseMapper.selectOne(customerBase);
		if(null == selectCustomerBase){
			customerBase.setPersonalId(personalId);
			customerBase.setStatus("00");//正常
			customerBase.setRegisterTime(new Date());
			customerBase.setCreateTime(new Date());
			customerBase.setUpdateTime(new Date());
			customerBaseMapper.insert(customerBase);
			personalId = customerBase.getPersonalId();
		}else{
			personalId = selectCustomerBase.getPersonalId();
		}
		
		PersonalBase personalBase = new PersonalBase();
		personalBase.setPlatformId(platformId);
		personalBase.setCustomerId(customerId);
		personalBase.setPersonalType("00");//注册用户
		personalBase.setPersonalId(personalId);
		PersonalBase selectPersonalBase = personalBaseMapper.selectOne(personalBase);
		if(null == selectPersonalBase){
			personalBaseMapper.insert(personalBase);
		}

		response.put("openId", openId);
		response.put("customerId", customerId);
		response.put("personalId", personalId);
		response.put("inviteResult", inviteMap);
		response.put("code", ResponseCode.OK.getCode());
		response.put("msg", ResponseCode.OK.getMessage());
		logger.info("微信授权响应。。。。。。{}", response);
		return response;
	}

	/**
	 * 小程序发送get请求 获取openId
	 * 
	 * @param url
	 *            路径
	 * @return
	 * @throws IOException
	 * @throws ClientProtocolException
	 */
	public static String wxSmallGetOpenId(String url) throws Exception {
		String strResult = null; // get请求返回结果
		CloseableHttpClient client = HttpClients.createDefault();

		HttpGet request = new HttpGet(url);// 发送get请求
		CloseableHttpResponse response = null;
		try {
			response = client.execute(request);
			// 请求发送成功，并得到响应
			logger.info("★★★★★★★★★★★★★★★★★★★★★★★★http response code:"+response.getStatusLine().getStatusCode());
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				strResult = EntityUtils.toString(response.getEntity()); // 读取服务器返回过来的json字符串数据
			} else {
				logger.info("get请求提交失败:" + url);
				return null;  
			}
		}catch (Exception e){
			logger.error("请求失败");
			throw new Exception("请求失败或者服务器错误");

		}
		return strResult;
	}

	/**
	 * 保存分享关系
	 * @param platformId
	 * @param customerId
	 * @param inviteId
	 * @return
	 */
	public Map<String, Object> saveInvieteRelation(String platformId, String customerId, String inviterId) {
		Map<String, Object> respMap = new HashMap<>();

		Map<String, Object> userMap = new HashMap<>();
		userMap.put("parentPerId", customerId);
		//将新用户与邀请人关联
		//判断邀请人属于哪级分销
		PersonalDistributionRelation distributionRelation = new PersonalDistributionRelation();
		distributionRelation.setPersonalId(customerId);
		List<PersonalDistributionRelation> customerRelationses = relationMapper.select(distributionRelation);

		int sz = customerRelationses.size();
		Date invitedTime = new Date();
		logger.info("邀请关系层级数------{}",sz);
		if (sz == 0) {
			//说明邀请人是顶级分销不是被邀请过的人 受要人是一级分销
			PersonalDistributionRelation invitedCustomer = new PersonalDistributionRelation();
			invitedCustomer.setPlatformId(platformId);
			invitedCustomer.setPersonalId(customerId);
			invitedCustomer.setParentLevel(1);
			invitedCustomer.setParentPerId(inviterId);
			invitedCustomer.setCreateTime(invitedTime);
			relationMapper.insert(invitedCustomer);
		}else if(sz == 1) {
			//说明邀请人是一级分销 受邀人是二级分销需要写两条条记录
			PersonalDistributionRelation invitedCustomer1 = new PersonalDistributionRelation();
			invitedCustomer1.setPlatformId(platformId);
			invitedCustomer1.setPersonalId(customerId);
			invitedCustomer1.setParentLevel(1);
			invitedCustomer1.setParentPerId(inviterId);
			invitedCustomer1.setCreateTime(invitedTime);
			relationMapper.insert(invitedCustomer1);
			//受邀人
			String parentId =  customerRelationses.get(0).getParentPerId();
			PersonalDistributionRelation invitedCustomer2 = new PersonalDistributionRelation();
			invitedCustomer2.setPlatformId(platformId);
			invitedCustomer2.setPersonalId(customerId);
			invitedCustomer2.setParentLevel(2);
			invitedCustomer2.setParentPerId(parentId);
			invitedCustomer2.setCreateTime(invitedTime);
			relationMapper.insert(invitedCustomer2);
		}else if (sz == 2) {
			//说明邀请人是二级分销 受邀人是三级分销需要写三条条记录
			PersonalDistributionRelation invitedCustomer = new PersonalDistributionRelation();
			invitedCustomer.setPlatformId(platformId);
			invitedCustomer.setPersonalId(customerId);
			invitedCustomer.setParentLevel(1);
			invitedCustomer.setParentPerId(inviterId);
			invitedCustomer.setCreateTime(invitedTime);
			relationMapper.insert(invitedCustomer);
			//查询出邀请人的parentId
			for (PersonalDistributionRelation customerRelations : customerRelationses) {
				String parentId = customerRelations.getParentPerId();
				//判断邀请人的上级位于三级分销中第几级
				PersonalDistributionRelation ic = new PersonalDistributionRelation();
				if (1 == customerRelations.getParentLevel()) {
					ic.setParentLevel(2);
				}else if (2 == customerRelations.getParentLevel()) {
					ic.setParentLevel(3);
				}
				ic.setPlatformId(platformId);
				ic.setPersonalId(customerId);
				ic.setParentPerId(parentId);
				ic.setCreateTime(invitedTime);
				relationMapper.insert(ic);
			}
		}else if (sz == 3) {
			//说明邀请人是三级分销 受邀人是邀请人的一级分销需要写一条记录
			PersonalDistributionRelation invitedCustomer = new PersonalDistributionRelation();
			invitedCustomer.setPlatformId(platformId);
			invitedCustomer.setPersonalId(customerId);
			invitedCustomer.setParentLevel(1);
			invitedCustomer.setParentPerId(inviterId);
			invitedCustomer.setCreateTime(invitedTime);
			relationMapper.insert(invitedCustomer);
		}

		//		CustomerAccount customerAccount = new CustomerAccount();
		//		customerAccount.setAccountType(AccountType.POINTS.getCode());
		//		customerAccount.setCustomerId(inviterId);
		//		customerAccountService.deposit(customerAccount, "5");
		//		return ResponseHelper.success(userMap,null, "00", "邀请成功");

		respMap.put("code", "00");
		respMap.put("msg", "邀请成功");
		return respMap;
	}


	/**
	 * 生成二维码流
	 * @param urls
	 * @param map
	 * @return
	 */
	public byte[]  doImgPost(String str) {

		byte[] result = null;
		//获取access_token
		StringBuilder url = new StringBuilder();
		url.append("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential");
		url.append("&appid=wx6225d2d623ff1b40");
		url.append("&secret=548bc84204dba0e8abd6402dbb04f2a2");
		String data = null;
		try {
			logger.info("小程序获取access_token第三方请求参数------{}", url.toString());
			data = wxSmallGetOpenId(url.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		logger.info("小程序获取access_token第三方返回参数------{}", JSONObject.fromObject(data));
		JSONObject json = JSONObject.fromObject(data);
		String access_token = String.valueOf(json.get("access_token"));

		//使用HTTPPost方法访问获取二维码链接url
		String urlStr = "https://api.weixin.qq.com/wxa/getwxacode?access_token="+access_token;
		HttpPost httpPost = new HttpPost(urlStr);
		//创建http连接客户端
		CloseableHttpClient client = HttpClients.createDefault();
		//设置头响应类型
		httpPost.addHeader("Content-Type", "application/json");

		Map<String, Object> paraMap = new HashMap<>();
		//二维码携带参数 不超过32位
		paraMap.put("scene", str);
		//二维码跳转页面
		paraMap.put("path", "pages/index/index");
		paraMap.put("width", 430);
		paraMap.put("auto_color", false);
		paraMap.put("line_color", "{\"r\":\"0\",\"g\":\"0\",\"b\":\"0\"}");
		try {
			// 设置请求的参数
			JSONObject postData = new JSONObject();
			for (Map.Entry<String, Object> entry : paraMap.entrySet()) {
				postData.put(entry.getKey(), entry.getValue());
			}
			httpPost.setEntity(new StringEntity(postData.toString(), "UTF-8"));
			logger.info("微信获取微信二维码post数据 " + postData.toString());
			//返回的post请求结果
			HttpResponse response = client.execute(httpPost);
			HttpEntity entity = response.getEntity();
			result = EntityUtils.toByteArray(entity);
		} catch (ConnectionPoolTimeoutException e) {
			logger.error("http get throw ConnectionPoolTimeoutException(wait time out)", e);
		} catch (ConnectTimeoutException e) {
			logger.error("http get throw ConnectTimeoutException", e);
		} catch (SocketTimeoutException e) {
			logger.error("http get throw SocketTimeoutException", e);
		} catch (Exception e) {
			logger.error("http get throw Exception", e);
		} finally {
			httpPost.releaseConnection();
		}
		//最后转成2进制图片流
		return result;
	}

}